package com.itheima.service;

import com.itheima.interceptor.UserHolder;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.dubbo.api.SoundApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Sound;
import com.tanhua.model.vo.SoundVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.Random;

/**
 * @author zwy
 */
@Service
public class SoundService {

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private SoundApi soundApi;

    @Autowired
    private UserInfoService userInfoService;

    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 发送声音
     */
    public String saveSound(MultipartFile[] soundFile) {
        try {
            Sound sound = new Sound();
            sound.setUserId(UserHolder.getUserId());

            //上传声音
            for (MultipartFile file : soundFile) {
                //调用声音上传工具类上传声音
                //获取上传的路径
                String soundUrl = ossTemplate.upload(file.getOriginalFilename(), file.getInputStream());
                //将路径保存到sound对象中
                sound.setSoundUrl(soundUrl);
            }
            return this.soundApi.saveSound(sound);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 接收声音
     */
    public SoundVo receiveSound() {
        //获取用户id
        Long userId = UserHolder.getUserId();

        //创建sound虚拟实体类
        SoundVo soundVo = new SoundVo();
        //创建存入redis中的key
        String getKey = "SOUND_GET_" + userId;
        //获取值
        String count = this.redisTemplate.opsForValue().get(getKey);
        //判断count如果为空,则赋给其默认值
        if (StringUtils.isEmpty(count)) {
            this.redisTemplate.opsForValue().set(getKey, String.valueOf(10));
            count = "10";
        }
        //将count转为integer类型
        Integer integer = Integer.valueOf(count);
        //判断integer是否大于零
        if (integer > 0) {
            //则调用接收方法
            List<Sound> sounds = this.soundApi.receiveSound(userId);
            //如果集合为空,则说明数据库中的声音已经被听完
            if (CollectionUtils.isEmpty(sounds)) {
                return null;
            }
            //查到一条排除自己声音之后的声音
            Sound sound = this.distinct(sounds);
            //给声音赋值
            soundVo.setUserId((sound.getUserId()));
            UserInfo userInfo = this.userInfoApi.findById(sound.getUserId());
            soundVo.setAvatar(userInfo.getAvatar());
            soundVo.setNickname(userInfo.getNickname());
            soundVo.setGender(userInfo.getGender());
            soundVo.setAge(userInfo.getAge());
            soundVo.setSoundUrl(sound.getSoundUrl());
            //让其接收语音的次数减少
            integer--;
            //获取指定key的值进行减1
            this.redisTemplate.opsForValue().decrement(getKey);
            //将自减过的次数存入对象
            soundVo.setRemainingTimes(integer);
            return soundVo;
        }
        //如果次数为零,则返回null
        return null;
    }

    /**
     * 去重  排除自己的声音
     *
     * @param sounds
     * @return
     */
    private Sound distinct(List<Sound> sounds) {
        //新建一个随机数
        Random random = new Random();
        int index = random.nextInt(sounds.size() - 1);
        if (index <= 0) {
            index = 0;
        }
        Sound sound = sounds.get(index);
        //将听过的语音全部存在redis中
        String gotKey = "SOUND_GOT_" + sound.getId();
        //获取值
        String count = this.redisTemplate.opsForValue().get(gotKey);
        //如果不为null,继续调用此方法,直至查出来的数据他没有听过
        if (count != null) {
            this.distinct(sounds);
        }
        //然后将其在redis中的值赋值为永久生效
        this.redisTemplate.opsForValue().set(gotKey, "1");
        //返回取出的数据
        return sound;
    }
}
